package org.aurora.common.util;


import org.apache.commons.lang3.StringUtils;
import org.aurora.common.exception.NetworkException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.net.util.IPAddressUtil;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class NetworkUtil {
    private static final Logger log = LoggerFactory.getLogger(NetworkUtil.class);
    private static String ipAddress;
    // 私有IP地址范围
    private static final long PRIVATE_IP_START_1 = ipToLong("10.0.0.0");
    private static final long PRIVATE_IP_END_1 = ipToLong("10.255.255.255");
    private static final long PRIVATE_IP_START_2 = ipToLong("172.16.0.0");
    private static final long PRIVATE_IP_END_2 = ipToLong("172.31.255.255");
    private static final long PRIVATE_IP_START_3 = ipToLong("192.168.0.0");
    private static final long PRIVATE_IP_END_3 = ipToLong("192.168.255.255");

    /**
     * 是否内网 ip
     * @param ip
     * @return
     */
    public static boolean isPrivateIP(String ip) {
        if (!IPAddressUtil.isIPv4LiteralAddress(ip)) {
            return false;
        }
        try {
            long ipLong = ipToLong(ip);
            return (ipLong >= PRIVATE_IP_START_1 && ipLong <= PRIVATE_IP_END_1) ||
                    (ipLong >= PRIVATE_IP_START_2 && ipLong <= PRIVATE_IP_END_2) ||
                    (ipLong >= PRIVATE_IP_START_3 && ipLong <= PRIVATE_IP_END_3);
        } catch (Exception e) {
            // 处理无效的IP地址
            return false;
        }
    }

    /**
     * 将 ip 地址转换为 long
     * @param ipAddress
     * @return
     */
    private static long ipToLong(String ipAddress) {
        String[] ipAddressInArray = ipAddress.split("\\.");
        long result = 0;
        for (int i = 0; i < ipAddressInArray.length; i++) {
            int power = 3 - i;
            int ipSegment = Integer.parseInt(ipAddressInArray[i]);
            result += ipSegment * Math.pow(256, power);
        }
        return result;
    }

    public static String getIpAddress() {
        if (StringUtils.isNotBlank(NetworkUtil.ipAddress)) {
            return NetworkUtil.ipAddress;
        }

        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                try {
                    NetworkInterface networkInterface = networkInterfaces.nextElement();

                    if (networkInterface.isLoopback() ||        // 是否为回环地址。回环地址一般指的是 127.0.0.1（IPv4） 或 ::1（IPv6），这些地址用于本地机器内部的网络通信测试
                            networkInterface.isVirtual() ||     // 虚拟网络接口。
                            !networkInterface.isUp()) {         // 是否激活
                        continue;
                    }

                    Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress inetAddress = inetAddresses.nextElement();
                        if (inetAddress instanceof Inet6Address) {
                            continue;
                        }

                        try {
                            if (inetAddress.isReachable(100)) {
                                NetworkUtil.ipAddress = inetAddress.getHostAddress();
                                return NetworkUtil.ipAddress;
                            }
                        } catch (Exception ignore) {
                        }
                    }
                } catch (Exception ignore) {
                }
            }
        } catch (Exception e) {
            log.error("get Ip Address error ", e);
            throw new NetworkException(e);
        }


        throw new NetworkException("get Ip Address is null");
    }

    public static String splicingAddr(String addr, int port) {
        return addr + ":" + port;
    }
}
